/**
 * Copyright (C) 2009 SC 4ViewSoft SRL
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package math.spbu.ru.historycharts.model;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import math.spbu.ru.historycharts.ChartsView;

/**
 * A series that includes 0 to many XYSeries.
 */
public class XYMultipleSeriesDataset implements Serializable {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	/**
	 * The included series.
	 */
	private List<XYSeries> mSeries = new ArrayList<XYSeries>();

	private double maxX = Double.MIN_VALUE, minX = Double.MAX_VALUE;

	/**
	 * Adds a new XY series to the list.
	 * 
	 * @param series
	 *            the XY series to ass
	 */
	public void addSeries(XYSeries series) {
		mSeries.add(series);
		updateRangeWithNewSeries(series);
	}

	/**
	 * Removes the XY series from the list.
	 * 
	 * @param index
	 *            the index in the series list of the series to remove
	 */
	public void removeSeries(int index) {
		mSeries.remove(index);
		updateRange();
	}

	/**
	 * Removes the XY series from the list.
	 * 
	 * @param series
	 *            the XY series to be removed
	 */
	public void removeSeries(XYSeries series) {
		mSeries.remove(series);
		updateRange();
	}

	/**
	 * Returns the XY series at the specified index.
	 * 
	 * @param index
	 *            the index
	 * @return the XY series at the index
	 */
	public XYSeries getSeriesAt(int index) {
		return mSeries.get(index);
	}

	/**
	 * Returns the XY series count.
	 * 
	 * @return the XY series count
	 */
	public int getSeriesCount() {
		return mSeries.size();
	}

	/**
	 * Returns an array of the XY series.
	 * 
	 * @return the XY series array
	 */
	public XYSeries[] getSeries() {
		return mSeries.toArray(new XYSeries[0]);
	}

	private void updateRangeWithNewSeries(XYSeries series) {
		maxX = Math.max(series.getMaxX(), maxX);
		minX = Math.min(series.getMinX(), minX);
	}

	public void updateRange() {
		double min = Long.MAX_VALUE;
		for (XYSeries series : mSeries) {
			min = Math.min(min, series.getMinX());
		}

		double max = Long.MIN_VALUE;
		for (XYSeries series : mSeries) {
			max = Math.max(max, series.getMaxX());
		}
		maxX = max;
		minX = min;
	}

	public void updateFirstLastElement() {
		for (XYSeries series : mSeries) {
			series.updateFirstLast();
		}
	}

	public void updateRangeY() {
		for (XYSeries series : mSeries) {
			series.initRangeY();
		}
	}

	public double getMinX() {
		return minX;
	}

	public double getMaxX() {
		return maxX;
	}

	public void clear() {
		for (XYSeries series : mSeries) {
			series.clear();
		}
	}

	public void getMisingData(double rangeStart, double rangeEnd) {
		if (minX > rangeStart) {
			List<DatePoint> list = ChartsView.getDataProvider()
					.getDinamicRateList((long) rangeStart, (long) minX);

			for (XYSeries series : mSeries) {
				series.addListInStart(list);
				updateRangeWithNewSeries(series);
			}
		}
		if (maxX < rangeEnd) {
			List<DatePoint> list = ChartsView.getDataProvider()
					.getDinamicRateList((long) maxX, (long) rangeEnd);

			for (XYSeries series : mSeries) {
				series.addListInEnd(list);
				updateRangeWithNewSeries(series);
			}
		}
	}

	public double getMaxY() {
		double max = Double.MIN_VALUE;
		for (XYSeries series : mSeries) {
			max = Math.max(max, series.getMaxY());
		}
		return max;
	}

	public double getMinY() {
		double min = Double.MAX_VALUE;
		for (XYSeries series : mSeries) {
			min = Math.min(min, series.getMinY());
		}
		return min;
	}

}
